//
//  File.swift
//  rxCoreLogic
//
//  Created by yq on 2021/1/21.
//

import Foundation

enum RXOperatorMarkdownText {
	
	static func description(for op: RxOperatorType) -> String {
		
		switch op {
			case .asyncSubject:
				return OperatorTextAsyncSubject
			case .binder:
				return OperatorTextBinder
			case .combinelaste:
				return OperatorTextCombineLaste
			case .distinctUntilChanged:
				return OperatorTextDistinctUntilChanged
			case .filter:
				return OperatorTextFilter
			case .flatMap:
				return OperatorTextFlatMap
			case .map:
				return OperatorTextMap
			case .just:
				return OperatorTextJust
			case .shareReplay:
				return OperatorTextShareReplay
			case .scan:
				return OperatorTextScan
			case .publishSubject:
				return OperatorTextPublishSubject
			case .replaySubject:
				return OperatorTextReplaySubject
			case .behaviorSubject:
				return OperatorTextBehaviorSubject
			case .elementAt:
				return OperatorTextElementAt
			case .empty:
				return OperatorTextEmpty
			case .flatMapLatest:
				return OperatorTextFlatMapLatest
			case .merge:
				return OperatorTextMerge
			case .publish:
				return OperatorTextPublish
			case .startWith:
				return OperatorTextStartWith
		}
	}
}




extension RXOperatorMarkdownText {
	
	static private let OperatorTextStartWith = """
### 操作符 startWith
`“startWith 操作符会在 Observable 头部插入一些元素。”`

#### 代码

```
“let disposeBag = DisposeBag()

Observable.of("🐶", "🐱", "🐭", "🐹")
	.startWith("1")
	.startWith("2")
	.startWith("3", "🅰️", "🅱️")
	.subscribe(onNext: { print($0) })
	.disposed(by: disposeBag)”
```

### 运行结果

```
“3
🅰️
🅱️
2
1
🐶
🐱
🐭
🐹”
```


"""
	
	static private let OperatorTextPublish = """
### 操作符 merge
`“publish 会将 Observable 转换为可被连接的 Observable。可被连接的 Observable 和普通的 Observable 十分相似，不过在被订阅后不会发出元素，直到 connect 操作符被应用为止。这样一来你可以控制 Observable 在什么时候开始发出元素。”`

#### 代码

```
	
let intSequeuece = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
	.publish()

_ = intSequeuece.subscribe(onNext: {
	print("Subscription 1:, Event:\"($0")")
})

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
	_ = intSequeuece.connect()
}

DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
	_ = intSequeuece.subscribe(onNext: {
		print("Subscription 2:, Event:\"($0")")
	})
}

DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
	_ = intSequeuece.subscribe(onNext: {
		print("Subscription 3:, Event:\"($0")")
	})
}
```

### 运行结果

```
Subscription 1:, Event:0
Subscription 1:, Event:1
Subscription 2:, Event:1
Subscription 1:, Event:2
Subscription 2:, Event:2
Subscription 1:, Event:3
Subscription 2:, Event:3
Subscription 3:, Event:3
Subscription 1:, Event:4
Subscription 2:, Event:4
Subscription 3:, Event:4
Subscription 1:, Event:5
Subscription 2:, Event:5
Subscription 3:, Event:5
Subscription 1:, Event:6
Subscription 2:, Event:6
Subscription 3:, Event:6
Subscription 1:, Event:7
Subscription 2:, Event:7
Subscription 3:, Event:7
Subscription 1:, Event:8
Subscription 2:, Event:8
Subscription 3:, Event:8
```


"""
	
	
	static private let OperatorTextMerge = """
### 操作符 merge
`“通过使用 merge 操作符你可以将多个 Observables 合并成一个，当某一个 Observable 发出一个元素时，他就将这个元素发出。”`

#### 代码

```
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()

Observable.of(subject1, subject2)
	.merge()
	.subscribe(onNext: { print($0) })
	.disposed(by: disposeBag)

subject1.onNext("🅰️")

subject1.onNext("🅱️")

subject2.onNext("①")

subject2.onNext("②")

subject1.onNext("🆎")

subject2.onNext("③")”

摘录来自: Unknown. “RxSwift 中文文档。” Apple Books.
```

### 运行结果

```
🅰️
🅱️
①
②
🆎
③
```


"""
	static private let OperatorTextFlatMapLatest = """
### 操作符 flatMapLatest
`“flatMapLatest操作符将源 Observable 的每一个元素应用一个转换方法，将他们转换成 Observables。一旦转换出一个新的 Observable，就只发出它的元素，旧的 Observables 的元素将被忽略掉。”`

#### 代码

```
	
let first = BehaviorSubject(value: "👦🏻")
let second = BehaviorSubject(value: "🅰️")
let variable = Variable(first)


variable.asObservable()
	.flatMapLatest{ $0} // 转换成 Observables
	.subscribe(onNext: {
		print($0)
	})
	.disposed(by: disposeBag)

first.onNext("🐱")
variable.value = second
second.onNext("🅱️")
first.onNext("🐶")
```

### 运行结果

```
👦🏻
🐱
🅰️
🅱️
```


"""
	
	static private let OperatorTextEmpty = """
### 操作符 empty
`“empty 操作符将创建一个 Observable，这个 Observable 只有一个完成事件。”`

#### 代码

```
let id = Observable<Int>.empty()
let id = Observable<Int>.create { observer in
	observer.onCompleted()
	return Disposables.create()
}
```

### 运行结果

```

```
"""
	
	static private let OperatorTextAsyncSubject = """
`将在源 Observer 产生完成事件后, 发出最后一个元素 ( 仅仅只有最后一个元素 ) ,
如果源 Observable 没有发出任何一个元素 ,只有一个完成事件.
那 AsyncSubject也只有一个完成事件.`

#### 操作符 asyncSubject

```
let subject = AsyncSubject<String>()
		subject
			.subscribe{ print(“Subscription: 1 Event:”,$0) }
			.disposed(by: disposeBag)
		subject.onNext(“🐶”)
		subject.onNext(“🐱”)
		subject.onNext(“🐹”)
		subject.onCompleted()
```

 运行结果:
```
 Subscription: 1 Event: next(🐹)
 Subscription: 1 Event: completed
```

"""
	static private let OperatorTextBinder = """

			   ### 操作符: Binder
			   `UI观察者在响应事件时只会处理 next 事件.
			   并且更新 UI 的操作必须在主线程上操作.
			   binder 可以更好的实现效果`

			   ### 代码
			   ```
			   let obs = BehaviorRelay(value: false)

			   obs.bind(to: self.btn.rx.isHidden).disposed(by: disposeBag)
			   ```
			   """
	static private let OperatorTextCombineLaste = """
				`publishSubject 表示一个对象，它既是一个可观察序列，也是一个观察者combineLastet 操作符将多个 Observables 中最新的元素通过一个函数组合起来, 然后将这个组合的结果发出来. 这些源 observables 中任何一个发出一个元素, 他都会发出一个元素( 前提是, 这些 Observables 曾经发出过元素).`

				#### 操作符  publishSubject
				```
				let first = PublishSubject<String>()
				let second = PublishSubject<String>()
				
				Observable.combineLatest(first, second) { $0 + $1}
				.subscribe(onNext: { print($0) })
				.disposed(by: disposeBag)
				
				first.onNext("1")
				second.onNext("A")
				
				first.onNext("2")
				second.onNext("B")
				
				second.onNext("C")
				second.onNext("D")
				
				first.onNext("3")
				first.onNext("4")
				
				```

				#### 运行结果

				```
				//        1A
				//        2A
				//        2B
				//        2C
				//        2D
				//        3D
				//        4D
				```

				"""
	
	
	static private let OperatorTextDistinctUntilChanged = """
					`distinctUntilChanged 操作符将阻止 Observable 发出相同的元素.如果后一个元素和前一个元素相同的, 那么这个元素将不会被发出来.如果后一个元素和和前一个元素不相同, 才会被发出来`
					### 操作符  distinctUntilChanged

					```
					Observable.of("1","2","2","2","3","4","5","5","6")
						.distinctUntilChanged()
						   .subscribe(onNext: {
							   print($0)
						   })
						   .disposed(by: disposeBag)
					```

					#### 运行结果

					```
					1
					2
					3
					4
					5
					6
					```
					"""
	static private let OperatorTextFilter = """
			`filter 通过你提供的判定方法过滤一个 Observable`

			#### 操作符 fliter
			```
			Observable<Int>.of(1,3,4,5,6,7,7,8,8,8)
			.filter { $0 > 3 }
			.subscribe(onNext: { print($0) })
			.disposed(by:disposeBag)
			```

			#### 运行结果

			```
			4
			5
			6
			7
			7
			8
			8
			8
			```
			"""
	
	static private let OperatorTextFlatMap = """
					```
					flatMap 将源 Observable 的每一个元素应用一个转换方法, 将他们转换成 Observables . 然后将这些 Observables 的元素合并之后再发送出来.
						 * 这个操作非常有用, 例如: 当 Observable 的元素本身具有其他的 Observable 时, 你可以将所有的子 Observables 的元素发送出来.
					```

					#### 操作符  flatMap

					```
						   
							let first = BehaviorSubject(value: "👦🏻")
							let second = BehaviorSubject(value: "🅰️")
							let variable = Variable(first)
					//        let variable = BehaviorRelay(value: first)
							
							variable.asObservable()
								.flatMap { $0 }
								.subscribe(onNext: { print("value : \"($0")") })
								.disposed(by: disposeBag)
							
							first.onNext("🐱")
							variable.value = second
							second.onNext("🅱️")
							first.onNext("🐶")
					```

					#### 运行结果

					```
							输出结果
							👦🏻
							🐱
							🅰️
							🅱️
							🐶
					```

					"""
	
	
	static private let OperatorTextMap = """
					`map操作符将源 Observable 的每个元素应用你提供的转换方法, 然后返回含有转换结果的 Observable`
					
					#### 操作符 Map
					```
					Observable.of(1,2,4,5,6,7)
					.map({$0 + 1})
					.subscribe(onNext: { print($0)} )
					.disposed(by:disposeBag)
					```
					#### 运行结果
					 
					```
					2
					3
					5
					6
					7
					8
					```
					"""
	static private let OperatorTextJust = """
					#### 操作符: just
					```
					//        let id = Observable.just(0)
					//        id.subscribe(onNext: {
					//            print("订阅序列的值 -  \"($0")")
					//        }).disposed(by: disposeBag)

					
					// 这个相当于
					let ob = Observable<Int>.create { (ob) -> Disposable in
					ob.onNext(0)
					ob.onCompleted()
					return Disposables.create()
					}
					
					ob.subscribe(onNext: { value in
					print("订阅到消息:\"(value")")
					},onCompleted: {
					print("完成")
					})
					.disposed(by:disposeBag)
					```
					"""
	static private let OperatorTextShareReplay =  """
				#### 操作符 ShareReplay
				```
				let ob = Observable<String>.create { (ob) -> Disposable in
				ob.onNext("A")
				ob.onNext("B")
				ob.onNext("C")
				ob.onCompleted()
				return Disposables.create()
				}.share(replay: 0)
				
				ob.subscribe(onNext: {
				print($0)
				})
				.disposed(by: disposeBag)
				```

				#### 运行结果:
				```
				A
				B
				C
				```
				"""
	static private let OperatorTextScan = """
					`持续的将 Observable 的每一个元素应用一个函数, 然后发出每一次函数返回的结果`

					#### 操作符 scan
					```
					Observable.of(10,100,1000)
					.scan(2) { (aggregateValue, newValue) in
					aggregateValue + newValue
					}
					.subscribe(onNext: {
					print($0)
					})
					.disposed(by: disposeBag)
					```

					#### 运行结果:
					```
					12, 112, 1112
					```
					"""
	
	static private let OperatorTextPublishSubject = """
				`订阅前产生的元素不会发送给观察者 ( observer )`

				```
				  let subject = PublishSubject<String>()
						subject.subscribe{print(“Subscription: 1 Event:”, $0) }
							.disposed(by: disposeBag)
						
						subject.onNext(“🐶”)
						subject.onNext(“🐱”)

						print(“\n”)
						subject.subscribe{print(“Subscription: 2 Event:”,$0) }
							.disposed(by: disposeBag)
						subject.onNext(“🅰️”)
						subject.onNext(“🅱️”)
				```

				####  运行结果:

				```
				  Subscription: 1 Event: next(🐶)
				  Subscription: 1 Event: next(🐱)
				  Subscription: 1 Event: next(🅰️)
				  Subscription: 2 Event: next(🅰️)
				  Subscription: 1 Event: next(🅱️)
				  Subscription: 2 Event: next(🅱️)
				```
				"""
	
	static private let OperatorTextReplaySubject = """
			   ```
			   “ReplaySubject 将对观察者发送全部的元素，无论观察者是何时进行订阅的。

			   这里存在多个版本的 ReplaySubject，有的只会将最新的 n 个元素发送给观察者，有的只会将限制时间段内最新的元素发送给观察者。

			   如果把 ReplaySubject 当作观察者来使用，注意不要在多个线程调用 onNext, onError 或 onCompleted。这样会导致无序调用，将造成意想不到的结果。”

			   摘录来自: Unknown. “RxSwift 中文文档。” Apple Books.
			   ```

			   ## 操作符 ReplaySubject


			   ### 代码
			   ```
			   let subject = ReplaySubject<String>.create(bufferSize: 1)
			   
			   subject.subscribe{ print("Subscription: 1 Event:", $0)  }
			   	.disposed(by: disposeBag)
			   subject.onNext("🐶")
			   subject.onNext("🐱")
			     
			   print("\n")
			   subject.subscribe {print("Subscription: 2 Event:", $0) }
			   	.disposed(by: disposeBag)
			   
			   subject.onNext("🅰️")
			   subject.onNext("🅱️")
			   
			   ```

			   ####  运行结果:

			   ```
			   /**
			   Subscription: 1 Event: next(🐶)
			   Subscription: 1 Event: next(🐱)


			   Subscription: 2 Event: next(🐱)
			   Subscription: 1 Event: next(🅰️)
			   Subscription: 2 Event: next(🅰️)
			   Subscription: 1 Event: next(🅱️)
			   Subscription: 2 Event: next(🅱️)
			   */
			   ```
			   """
	static private let OperatorTextBehaviorSubject =  """
				```
				“当观察者对 BehaviorSubject 进行订阅时，它会将源 Observable 中最新的元素发送出来（如果不存在最新的元素，就发出默认元素）。然后将随后产生的元素发送出来。”

				摘录来自: Unknown. “RxSwift 中文文档。” Apple Books.
				```


				## 操作符 BehaviorSubject

				### 代码
				```
				let subject = BehaviorSubject(value: "🔴")

				subject.subscribe { print("Subscription: 1 Event:",$0)}
				.disposed(by: disposeBag)

				print("\n")
				subject.onNext("🐶")
				subject.onNext("🐱")
				subject.subscribe { print("Subscription: 2 Event:",$0)}
				.disposed(by: disposeBag)

				print("\n")
				subject.onNext("🅰️")
				subject.onNext("🅱️")

				subject.subscribe { print("Subscription 3 Event:",$0)}
				.disposed(by: disposeBag)

				print("\n")
				subject.onNext("🍐")
				subject.onNext("🍊")

				```
				####  运行结果:

				```
				Subscription: 1 Event: next(🔴)


				Subscription: 1 Event: next(🐶)
				Subscription: 1 Event: next(🐱)
				Subscription: 2 Event: next(🐱)


				Subscription: 1 Event: next(🅰️)
				Subscription: 2 Event: next(🅰️)
				Subscription: 1 Event: next(🅱️)
				Subscription: 2 Event: next(🅱️)
				Subscription 3 Event: next(🅱️)


				Subscription: 1 Event: next(🍐)
				Subscription: 2 Event: next(🍐)
				Subscription 3 Event: next(🍐)
				Subscription: 1 Event: next(🍊)
				Subscription: 2 Event: next(🍊)
				Subscription 3 Event: next(🍊)
				```


				"""
	
	static private var OperatorTextElementAt = """

	`“elementAt 操作符将拉取 Observable 序列中指定索引数的元素，然后将它作为唯一的元素发出。”`


	### 操作符 ElementAt


	#### 代码

	```
	“let disposeBag = DisposeBag()

	Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
	.elementAt(3)
	.subscribe(onNext: { print($0) })
	.disposed(by: disposeBag)”

	摘录来自: Unknown. “RxSwift 中文文档。” Apple Books.
	```

	### 运行结果

	```
	🐸
	```


	"""
	
}
